package cn.edu.scau.cmi.hombio.service;

import cn.edu.scau.cmi.hombio.dao.CureMedicineDAO;
import cn.edu.scau.cmi.hombio.dao.CureTaskMedicineDAO;
import cn.edu.scau.cmi.hombio.dao.MedicineDAO;
import cn.edu.scau.cmi.hombio.dao.MedicineStorageDetailDAO;
import cn.edu.scau.cmi.hombio.dao.MedicineSupplierDAO;
import cn.edu.scau.cmi.hombio.dao.MedicineTakeDetailDAO;
import cn.edu.scau.cmi.hombio.dao.PreventionTypeDAO;

import cn.edu.scau.cmi.hombio.domain.CureMedicine;
import cn.edu.scau.cmi.hombio.domain.CureTaskMedicine;
import cn.edu.scau.cmi.hombio.domain.Medicine;
import cn.edu.scau.cmi.hombio.domain.MedicineStorageDetail;
import cn.edu.scau.cmi.hombio.domain.MedicineSupplier;
import cn.edu.scau.cmi.hombio.domain.MedicineTakeDetail;
import cn.edu.scau.cmi.hombio.domain.PreventionType;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**
 * Spring service that handles CRUD requests for Medicine entities
 * 
 */

@Service("MedicineService")

@Transactional
public class MedicineServiceImpl implements MedicineService {

	/**
	 * DAO injected by Spring that manages CureMedicine entities
	 * 
	 */
	@Autowired
	private CureMedicineDAO cureMedicineDAO;

	/**
	 * DAO injected by Spring that manages CureTaskMedicine entities
	 * 
	 */
	@Autowired
	private CureTaskMedicineDAO cureTaskMedicineDAO;

	/**
	 * DAO injected by Spring that manages Medicine entities
	 * 
	 */
	@Autowired
	private MedicineDAO medicineDAO;

	/**
	 * DAO injected by Spring that manages MedicineStorageDetail entities
	 * 
	 */
	@Autowired
	private MedicineStorageDetailDAO medicineStorageDetailDAO;

	/**
	 * DAO injected by Spring that manages MedicineSupplier entities
	 * 
	 */
	@Autowired
	private MedicineSupplierDAO medicineSupplierDAO;

	/**
	 * DAO injected by Spring that manages MedicineTakeDetail entities
	 * 
	 */
	@Autowired
	private MedicineTakeDetailDAO medicineTakeDetailDAO;

	/**
	 * DAO injected by Spring that manages PreventionType entities
	 * 
	 */
	@Autowired
	private PreventionTypeDAO preventionTypeDAO;

	/**
	 * Instantiates a new MedicineServiceImpl.
	 *
	 */
	public MedicineServiceImpl() {
	}

	/**
	 * Delete an existing MedicineSupplier entity
	 * 
	 */
	@Transactional
	public Medicine deleteMedicineMedicineSuppliers(Integer medicine_id, Integer related_medicinesuppliers_id) {
		MedicineSupplier related_medicinesuppliers = medicineSupplierDAO.findMedicineSupplierByPrimaryKey(related_medicinesuppliers_id, -1, -1);

		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(medicine_id, -1, -1);

		related_medicinesuppliers.setMedicine(null);
		medicine.getMedicineSuppliers().remove(related_medicinesuppliers);

		medicineSupplierDAO.remove(related_medicinesuppliers);
		medicineSupplierDAO.flush();

		return medicine;
	}

	/**
	 * Load an existing Medicine entity
	 * 
	 */
	@Transactional
	public Set<Medicine> loadMedicines() {
		return medicineDAO.findAllMedicines();
	}

	/**
	 * Save an existing MedicineStorageDetail entity
	 * 
	 */
	@Transactional
	public Medicine saveMedicineMedicineStorageDetails(Integer id, MedicineStorageDetail related_medicinestoragedetails) {
		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(id, -1, -1);
		MedicineStorageDetail existingmedicineStorageDetails = medicineStorageDetailDAO.findMedicineStorageDetailByPrimaryKey(related_medicinestoragedetails.getId());

		// copy into the existing record to preserve existing relationships
		if (existingmedicineStorageDetails != null) {
			existingmedicineStorageDetails.setId(related_medicinestoragedetails.getId());
			existingmedicineStorageDetails.setTraceCode(related_medicinestoragedetails.getTraceCode());
			existingmedicineStorageDetails.setIsPutaway(related_medicinestoragedetails.getIsPutaway());
			existingmedicineStorageDetails.setIsUseout(related_medicinestoragedetails.getIsUseout());
			related_medicinestoragedetails = existingmedicineStorageDetails;
		}

		related_medicinestoragedetails.setMedicine(medicine);
		medicine.getMedicineStorageDetails().add(related_medicinestoragedetails);
		related_medicinestoragedetails = medicineStorageDetailDAO.store(related_medicinestoragedetails);
		medicineStorageDetailDAO.flush();

		medicine = medicineDAO.store(medicine);
		medicineDAO.flush();

		return medicine;
	}

	/**
	 */
	@Transactional
	public Medicine findMedicineByPrimaryKey(Integer id) {
		return medicineDAO.findMedicineByPrimaryKey(id);
	}

	/**
	 * Delete an existing MedicineStorageDetail entity
	 * 
	 */
	@Transactional
	public Medicine deleteMedicineMedicineStorageDetails(Integer medicine_id, Integer related_medicinestoragedetails_id) {
		MedicineStorageDetail related_medicinestoragedetails = medicineStorageDetailDAO.findMedicineStorageDetailByPrimaryKey(related_medicinestoragedetails_id, -1, -1);

		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(medicine_id, -1, -1);

		related_medicinestoragedetails.setMedicine(null);
		medicine.getMedicineStorageDetails().remove(related_medicinestoragedetails);

		medicineStorageDetailDAO.remove(related_medicinestoragedetails);
		medicineStorageDetailDAO.flush();

		return medicine;
	}

	/**
	 * Delete an existing MedicineTakeDetail entity
	 * 
	 */
	@Transactional
	public Medicine deleteMedicineMedicineTakeDetails(Integer medicine_id, Integer related_medicinetakedetails_id) {
		MedicineTakeDetail related_medicinetakedetails = medicineTakeDetailDAO.findMedicineTakeDetailByPrimaryKey(related_medicinetakedetails_id, -1, -1);

		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(medicine_id, -1, -1);

		related_medicinetakedetails.setMedicine(null);
		medicine.getMedicineTakeDetails().remove(related_medicinetakedetails);

		medicineTakeDetailDAO.remove(related_medicinetakedetails);
		medicineTakeDetailDAO.flush();

		return medicine;
	}

	/**
	 * Return a count of all Medicine entity
	 * 
	 */
	@Transactional
	public Integer countMedicines() {
		return ((Long) medicineDAO.createQuerySingleResult("select count(o) from Medicine o").getSingleResult()).intValue();
	}

	/**
	 * Delete an existing PreventionType entity
	 * 
	 */
	@Transactional
	public Medicine deleteMedicinePreventionTypesForMedicineId(Integer medicine_id, Integer related_preventiontypesformedicineid_id) {
		PreventionType related_preventiontypesformedicineid = preventionTypeDAO.findPreventionTypeByPrimaryKey(related_preventiontypesformedicineid_id, -1, -1);

		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(medicine_id, -1, -1);

		related_preventiontypesformedicineid.setMedicineByReportMedicineId(null);
		medicine.getPreventionTypesForReportMedicineId().remove(related_preventiontypesformedicineid);

		preventionTypeDAO.remove(related_preventiontypesformedicineid);
		preventionTypeDAO.flush();

		return medicine;
	}

	/**
	 * Delete an existing PreventionType entity
	 * 
	 */
	@Transactional
	public Medicine deleteMedicinePreventionTypesForReportMedicineId(Integer medicine_id, Integer related_preventiontypesforreportmedicineid_id) {
		PreventionType related_preventiontypesforreportmedicineid = preventionTypeDAO.findPreventionTypeByPrimaryKey(related_preventiontypesforreportmedicineid_id, -1, -1);

		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(medicine_id, -1, -1);

		related_preventiontypesforreportmedicineid.setMedicineByReportMedicineId(null);
		medicine.getPreventionTypesForReportMedicineId().remove(related_preventiontypesforreportmedicineid);

		preventionTypeDAO.remove(related_preventiontypesforreportmedicineid);
		preventionTypeDAO.flush();

		return medicine;
	}

	/**
	 * Save an existing CureTaskMedicine entity
	 * 
	 */
	@Transactional
	public Medicine saveMedicineCureTaskMedicines(Integer id, CureTaskMedicine related_curetaskmedicines) {
		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(id, -1, -1);
		CureTaskMedicine existingcureTaskMedicines = cureTaskMedicineDAO.findCureTaskMedicineByPrimaryKey(related_curetaskmedicines.getId());

		// copy into the existing record to preserve existing relationships
		if (existingcureTaskMedicines != null) {
			existingcureTaskMedicines.setId(related_curetaskmedicines.getId());
			existingcureTaskMedicines.setQuantity(related_curetaskmedicines.getQuantity());
			existingcureTaskMedicines.setMemo(related_curetaskmedicines.getMemo());
			related_curetaskmedicines = existingcureTaskMedicines;
		}

		related_curetaskmedicines.setMedicine(medicine);
		medicine.getCureTaskMedicines().add(related_curetaskmedicines);
		related_curetaskmedicines = cureTaskMedicineDAO.store(related_curetaskmedicines);
		cureTaskMedicineDAO.flush();

		medicine = medicineDAO.store(medicine);
		medicineDAO.flush();

		return medicine;
	}

	/**
	 * Save an existing PreventionType entity
	 * 
	 */
	@Transactional
	public Medicine saveMedicinePreventionTypesForReportMedicineId(Integer id, PreventionType related_preventiontypesforreportmedicineid) {
		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(id, -1, -1);
		PreventionType existingpreventionTypesForReportMedicineId = preventionTypeDAO.findPreventionTypeByPrimaryKey(related_preventiontypesforreportmedicineid.getId());

		// copy into the existing record to preserve existing relationships
		if (existingpreventionTypesForReportMedicineId != null) {
			existingpreventionTypesForReportMedicineId.setId(related_preventiontypesforreportmedicineid.getId());
			existingpreventionTypesForReportMedicineId.setName(related_preventiontypesforreportmedicineid.getName());
			existingpreventionTypesForReportMedicineId.setReportQuality(related_preventiontypesforreportmedicineid.getReportQuality());
			existingpreventionTypesForReportMedicineId.setQuality(related_preventiontypesforreportmedicineid.getQuality());
			existingpreventionTypesForReportMedicineId.setMemo(related_preventiontypesforreportmedicineid.getMemo());
			related_preventiontypesforreportmedicineid = existingpreventionTypesForReportMedicineId;
		} else {
			related_preventiontypesforreportmedicineid = preventionTypeDAO.store(related_preventiontypesforreportmedicineid);
			preventionTypeDAO.flush();
		}

		related_preventiontypesforreportmedicineid.setMedicineByReportMedicineId(medicine);
		medicine.getPreventionTypesForReportMedicineId().add(related_preventiontypesforreportmedicineid);
		related_preventiontypesforreportmedicineid = preventionTypeDAO.store(related_preventiontypesforreportmedicineid);
		preventionTypeDAO.flush();

		medicine = medicineDAO.store(medicine);
		medicineDAO.flush();

		return medicine;
	}

	/**
	 * Delete an existing CureTaskMedicine entity
	 * 
	 */
	@Transactional
	public Medicine deleteMedicineCureTaskMedicines(Integer medicine_id, Integer related_curetaskmedicines_id) {
		CureTaskMedicine related_curetaskmedicines = cureTaskMedicineDAO.findCureTaskMedicineByPrimaryKey(related_curetaskmedicines_id, -1, -1);

		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(medicine_id, -1, -1);

		related_curetaskmedicines.setMedicine(null);
		medicine.getCureTaskMedicines().remove(related_curetaskmedicines);

		cureTaskMedicineDAO.remove(related_curetaskmedicines);
		cureTaskMedicineDAO.flush();

		return medicine;
	}

	/**
	 * Save an existing Medicine entity
	 * 
	 */
	@Transactional
	public void saveMedicine(Medicine medicine) {
		Medicine existingMedicine = medicineDAO.findMedicineByPrimaryKey(medicine.getId());

		if (existingMedicine != null) {
			if (existingMedicine != medicine) {
				existingMedicine.setId(medicine.getId());
				existingMedicine.setName(medicine.getName());
				existingMedicine.setNumber(medicine.getNumber());
				existingMedicine.setCompany(medicine.getCompany());
				existingMedicine.setQuantityPerCase(medicine.getQuantityPerCase());
				existingMedicine.setQuantityPerBox(medicine.getQuantityPerBox());
				existingMedicine.setPhone(medicine.getPhone());
				existingMedicine.setMemo(medicine.getMemo());
			}
			medicine = medicineDAO.store(existingMedicine);
		} else {
			medicine = medicineDAO.store(medicine);
		}
		medicineDAO.flush();
	}

	/**
	 * Save an existing MedicineTakeDetail entity
	 * 
	 */
	@Transactional
	public Medicine saveMedicineMedicineTakeDetails(Integer id, MedicineTakeDetail related_medicinetakedetails) {
		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(id, -1, -1);
		MedicineTakeDetail existingmedicineTakeDetails = medicineTakeDetailDAO.findMedicineTakeDetailByPrimaryKey(related_medicinetakedetails.getId());

		// copy into the existing record to preserve existing relationships
		if (existingmedicineTakeDetails != null) {
			existingmedicineTakeDetails.setId(related_medicinetakedetails.getId());
			existingmedicineTakeDetails.setTraceCode(related_medicinetakedetails.getTraceCode());
			existingmedicineTakeDetails.setBoxTraceCode(related_medicinetakedetails.getBoxTraceCode());
			existingmedicineTakeDetails.setCaseTraceCode(related_medicinetakedetails.getCaseTraceCode());
			existingmedicineTakeDetails.setIsBox(related_medicinetakedetails.getIsBox());
			related_medicinetakedetails = existingmedicineTakeDetails;
		}

		related_medicinetakedetails.setMedicine(medicine);
		medicine.getMedicineTakeDetails().add(related_medicinetakedetails);
		related_medicinetakedetails = medicineTakeDetailDAO.store(related_medicinetakedetails);
		medicineTakeDetailDAO.flush();

		medicine = medicineDAO.store(medicine);
		medicineDAO.flush();

		return medicine;
	}

	/**
	 * Save an existing MedicineSupplier entity
	 * 
	 */
	@Transactional
	public Medicine saveMedicineMedicineSuppliers(Integer id, MedicineSupplier related_medicinesuppliers) {
		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(id, -1, -1);
		MedicineSupplier existingmedicineSuppliers = medicineSupplierDAO.findMedicineSupplierByPrimaryKey(related_medicinesuppliers.getId());

		// copy into the existing record to preserve existing relationships
		if (existingmedicineSuppliers != null) {
			existingmedicineSuppliers.setId(related_medicinesuppliers.getId());
			related_medicinesuppliers = existingmedicineSuppliers;
		} else {
			related_medicinesuppliers = medicineSupplierDAO.store(related_medicinesuppliers);
			medicineSupplierDAO.flush();
		}

		related_medicinesuppliers.setMedicine(medicine);
		medicine.getMedicineSuppliers().add(related_medicinesuppliers);
		related_medicinesuppliers = medicineSupplierDAO.store(related_medicinesuppliers);
		medicineSupplierDAO.flush();

		medicine = medicineDAO.store(medicine);
		medicineDAO.flush();

		return medicine;
	}

	/**
	 * Save an existing CureMedicine entity
	 * 
	 */
	@Transactional
	public Medicine saveMedicineCureMedicines(Integer id, CureMedicine related_curemedicines) {
		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(id, -1, -1);
		CureMedicine existingcureMedicines = cureMedicineDAO.findCureMedicineByPrimaryKey(related_curemedicines.getId());

		// copy into the existing record to preserve existing relationships
		if (existingcureMedicines != null) {
			existingcureMedicines.setId(related_curemedicines.getId());
			existingcureMedicines.setQuantity(related_curemedicines.getQuantity());
			existingcureMedicines.setMemo(related_curemedicines.getMemo());
			related_curemedicines = existingcureMedicines;
		}

		related_curemedicines.setMedicine(medicine);
		medicine.getCureMedicines().add(related_curemedicines);
		related_curemedicines = cureMedicineDAO.store(related_curemedicines);
		cureMedicineDAO.flush();

		medicine = medicineDAO.store(medicine);
		medicineDAO.flush();

		return medicine;
	}

	/**
	 * Delete an existing CureMedicine entity
	 * 
	 */
	@Transactional
	public Medicine deleteMedicineCureMedicines(Integer medicine_id, Integer related_curemedicines_id) {
		CureMedicine related_curemedicines = cureMedicineDAO.findCureMedicineByPrimaryKey(related_curemedicines_id, -1, -1);

		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(medicine_id, -1, -1);

		related_curemedicines.setMedicine(null);
		medicine.getCureMedicines().remove(related_curemedicines);

		cureMedicineDAO.remove(related_curemedicines);
		cureMedicineDAO.flush();

		return medicine;
	}

	/**
	 * Return all Medicine entity
	 * 
	 */
	@Transactional
	public List<Medicine> findAllMedicines(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Medicine>(medicineDAO.findAllMedicines(startResult, maxRows));
	}

	/**
	 * Save an existing PreventionType entity
	 * 
	 */
	@Transactional
	public Medicine saveMedicinePreventionTypesForMedicineId(Integer id, PreventionType related_preventiontypesformedicineid) {
		Medicine medicine = medicineDAO.findMedicineByPrimaryKey(id, -1, -1);
		PreventionType existingpreventionTypesForMedicineId = preventionTypeDAO.findPreventionTypeByPrimaryKey(related_preventiontypesformedicineid.getId());

		// copy into the existing record to preserve existing relationships
		if (existingpreventionTypesForMedicineId != null) {
			existingpreventionTypesForMedicineId.setId(related_preventiontypesformedicineid.getId());
			existingpreventionTypesForMedicineId.setName(related_preventiontypesformedicineid.getName());
			existingpreventionTypesForMedicineId.setReportQuality(related_preventiontypesformedicineid.getReportQuality());
			existingpreventionTypesForMedicineId.setQuality(related_preventiontypesformedicineid.getQuality());
			existingpreventionTypesForMedicineId.setMemo(related_preventiontypesformedicineid.getMemo());
			related_preventiontypesformedicineid = existingpreventionTypesForMedicineId;
		} else {
			related_preventiontypesformedicineid = preventionTypeDAO.store(related_preventiontypesformedicineid);
			preventionTypeDAO.flush();
		}

		related_preventiontypesformedicineid.setMedicineByReportMedicineId(medicine);
		medicine.getPreventionTypesForReportMedicineId().add(related_preventiontypesformedicineid);
		related_preventiontypesformedicineid = preventionTypeDAO.store(related_preventiontypesformedicineid);
		preventionTypeDAO.flush();

		medicine = medicineDAO.store(medicine);
		medicineDAO.flush();

		return medicine;
	}

	/**
	 * Delete an existing Medicine entity
	 * 
	 */
	@Transactional
	public void deleteMedicine(Medicine medicine) {
		medicineDAO.remove(medicine);
		medicineDAO.flush();
	}
}
